package com.gmail.avereshchaga.db.dao;

import com.gmail.avereshchaga.db.entity.IInvoice;
import com.gmail.avereshchaga.db.entity.InvoiceImpl;
import java.util.Date;
import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

/**
 *
 * @author <a href="mailto:avereshchaga@gmail.com">Vereshchaga Alexey</a>
 */
@Repository
public class InvoiceDAOImpl implements IInvoiceDAO {

    @Autowired
    private SessionFactory sessionFactory;

    @Override
    public void createInvoice(IInvoice invoice) {
        sessionFactory.getCurrentSession().save(invoice);
    }

    @Override
    public void updateInvoice(IInvoice invoice) {
        sessionFactory.getCurrentSession().update(invoice);
    }

    @Override
    public void deleteInvoice(IInvoice invoice) {
        sessionFactory.getCurrentSession().delete(invoice);
    }

    @Override
    public List<IInvoice> findAll(Integer page) {
        Session session = sessionFactory.getCurrentSession();
        Criteria crit = session.createCriteria(InvoiceImpl.class);
        crit.addOrder(Order.asc("id"))
                .setFirstResult(page * 100)
                .setMaxResults(100);
        List<IInvoice> invoices = crit.list();
        return invoices;

    }

    @Override
    public IInvoice findById(Long id) {
        Session session = sessionFactory.getCurrentSession();
        Criteria crit = session.createCriteria(InvoiceImpl.class);
        crit.add(Restrictions.eq("id", id));
        IInvoice invoice = (InvoiceImpl) crit.uniqueResult();
        return invoice;
    }

    @Override
    public List<IInvoice> findByFilter(Date date, String name, Integer page) {

        Query q = sessionFactory.getCurrentSession()
                .createQuery("from InvoiceImpl invoice where invoice.createdAt = :date"
                + " and (lower(invoice.user.firstName) like :name or lower(invoice.user.lastName) like :name"
                + " or ((lower(invoice.user.firstName)  || ' ' || lower(invoice.user.lastName)) like :name)"
                + " or ((lower(invoice.user.lastName)  || ' ' || lower(invoice.user.firstName)) like :name))");
        q.setDate("date", date);
        q.setString("name", name.trim().toLowerCase() + "%");
        q.setMaxResults(100);
        q.setFirstResult(page * 100);
        List<IInvoice> invoices = q.list();

        return invoices;
    }

    @Override
    public List<IInvoice> findByName(String name, Integer page) {
        Query q = sessionFactory.getCurrentSession()
                .createQuery("from InvoiceImpl invoice where"
                + " lower(invoice.user.firstName) like :name or lower(invoice.user.lastName) like :name"
                + " or ((lower(invoice.user.firstName) || ' ' || lower(invoice.user.lastName)) like :name)"
                + " or ((lower(invoice.user.lastName) || ' ' || lower(invoice.user.firstName)) like :name)");
        q.setString("name", name.trim().toLowerCase() + "%");
        q.setMaxResults(100);
        q.setFirstResult(page * 100);
        List<IInvoice> invoices = q.list();

        return invoices;
    }
}
